<html>
<head><meta charset="utf-8"><title>Why would a for loop not force a move into a closure? · general · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/index.html">general</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Why.20would.20a.20for.20loop.20not.20force.20a.20move.20into.20a.20closure.3F.html">Why would a for loop not force a move into a closure?</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="231254242"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Why%20would%20a%20for%20loop%20not%20force%20a%20move%20into%20a%20closure%3F/near/231254242" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Why.20would.20a.20for.20loop.20not.20force.20a.20move.20into.20a.20closure.3F.html#231254242">(Mar 22 2021 at 01:35)</a>:</h4>
<p>With this example, I'd expect that <code>chunk</code> would be moved into the innermost closure because the <code>for</code> loop should take ownership of it (via the call to <code>IntoIterator</code>):</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">adder</span><span class="p">(</span><span class="n">values</span>: <span class="kp">&amp;</span><span class="p">[</span><span class="kt">i64</span><span class="p">])</span><span class="w">  </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">crossbeam</span>::<span class="n">scope</span><span class="p">(</span><span class="o">|</span><span class="n">scope</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="k">for</span><span class="w"> </span><span class="n">chunk</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">values</span><span class="p">.</span><span class="n">chunks</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">            </span><span class="kd">let</span><span class="w"> </span><span class="n">chunk</span>: <span class="kp">&amp;</span><span class="p">[</span><span class="kt">i64</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">chunk</span><span class="p">;</span><span class="w"> </span><span class="c1">// type assertion</span>
<span class="w">            </span><span class="n">scope</span><span class="p">.</span><span class="n">spawn</span><span class="p">(</span><span class="o">|</span><span class="n">_</span><span class="o">|</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">chunk</span><span class="w"> </span><span class="p">{});</span><span class="w"></span>
<span class="w">        </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="p">})</span><span class="w"></span>
<span class="w">    </span><span class="p">.</span><span class="n">expect</span><span class="p">(</span><span class="s">"error"</span><span class="p">)</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>However, the compiler only borrows <code>chunk</code>:</p>
<div class="codehilite"><pre><span></span><code>error[E0373]: closure may outlive the current function, but it borrows `chunk`, which is owned by the current function
 --&gt; src/lib.rs:5:25
  |
2 |     crossbeam::scope(|scope| {
  |                       ----- has type `&amp;Scope&lt;&#39;1&gt;`
...
5 |             scope.spawn(|_| for _ in chunk {});
  |                         ^^^          ----- `chunk` is borrowed here
  |                         |
  |                         may outlive borrowed value `chunk`
  |
note: function requires argument type to outlive `&#39;1`
 --&gt; src/lib.rs:5:13
  |
5 |             scope.spawn(|_| for _ in chunk {});
  |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: to force the closure to take ownership of `chunk` (and any other referenced variables), use the `move` keyword
  |
5 |             scope.spawn(move |_| for _ in chunk {});
  |                         ^^^^^^^^
</code></pre></div>
<p>The <code>move</code> suggestion works, but I'm surprised that it's needed.</p>



<a name="231255103"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Why%20would%20a%20for%20loop%20not%20force%20a%20move%20into%20a%20closure%3F/near/231255103" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lukas Wirth <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Why.20would.20a.20for.20loop.20not.20force.20a.20move.20into.20a.20closure.3F.html#231255103">(Mar 22 2021 at 01:55)</a>:</h4>
<p>The <code>chunks</code> call takes the slice by ref, so the closure doesn't require ownership of the slice</p>



<a name="231255802"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Why%20would%20a%20for%20loop%20not%20force%20a%20move%20into%20a%20closure%3F/near/231255802" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Why.20would.20a.20for.20loop.20not.20force.20a.20move.20into.20a.20closure.3F.html#231255802">(Mar 22 2021 at 02:06)</a>:</h4>
<p>But the <em>inner</em> closure is the one that needs <code>move</code> applied, not the outer one.</p>



<a name="231255825"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Why%20would%20a%20for%20loop%20not%20force%20a%20move%20into%20a%20closure%3F/near/231255825" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Why.20would.20a.20for.20loop.20not.20force.20a.20move.20into.20a.20closure.3F.html#231255825">(Mar 22 2021 at 02:07)</a>:</h4>
<p>e.g. <code>chunk</code> needs to be moved, not <code>values</code></p>



<a name="231256098"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Why%20would%20a%20for%20loop%20not%20force%20a%20move%20into%20a%20closure%3F/near/231256098" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lukas Wirth <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Why.20would.20a.20for.20loop.20not.20force.20a.20move.20into.20a.20closure.3F.html#231256098">(Mar 22 2021 at 02:12)</a>:</h4>
<p>Oh I missed the <code>innermost</code>, sorry</p>



<a name="231261062"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Why%20would%20a%20for%20loop%20not%20force%20a%20move%20into%20a%20closure%3F/near/231261062" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jane Lusby <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Why.20would.20a.20for.20loop.20not.20force.20a.20move.20into.20a.20closure.3F.html#231261062">(Mar 22 2021 at 04:00)</a>:</h4>
<p>Do non move closures ever take ownership of values? I would not expect this to work without move</p>



<a name="231261444"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Why%20would%20a%20for%20loop%20not%20force%20a%20move%20into%20a%20closure%3F/near/231261444" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jane Lusby <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Why.20would.20a.20for.20loop.20not.20force.20a.20move.20into.20a.20closure.3F.html#231261444">(Mar 22 2021 at 04:07)</a>:</h4>
<p>Reading the reference now, TIL they can</p>



<a name="231261664"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Why%20would%20a%20for%20loop%20not%20force%20a%20move%20into%20a%20closure%3F/near/231261664" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jane Lusby <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Why.20would.20a.20for.20loop.20not.20force.20a.20move.20into.20a.20closure.3F.html#231261664">(Mar 22 2021 at 04:11)</a>:</h4>
<blockquote>
<p>The compiler prefers to capture a closed-over variable by immutable borrow, followed by unique immutable borrow (see below), by mutable borrow, and finally by move. It will pick the first choice of these that allows the closure to compile. <strong>The choice is made only with regards to the contents of the closure expression; the compiler does not take into account surrounding code, such as the lifetimes of involved variables.</strong></p>
</blockquote>



<a name="231261675"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Why%20would%20a%20for%20loop%20not%20force%20a%20move%20into%20a%20closure%3F/near/231261675" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jane Lusby <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Why.20would.20a.20for.20loop.20not.20force.20a.20move.20into.20a.20closure.3F.html#231261675">(Mar 22 2021 at 04:11)</a>:</h4>
<p>I'm guessing this is because the pass where the compiler assumes a reference will work happens before borrowck</p>



<a name="231261780"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Why%20would%20a%20for%20loop%20not%20force%20a%20move%20into%20a%20closure%3F/near/231261780" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jane Lusby <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Why.20would.20a.20for.20loop.20not.20force.20a.20move.20into.20a.20closure.3F.html#231261780">(Mar 22 2021 at 04:13)</a>:</h4>
<p><span class="user-mention" data-user-id="116155">@Jake Goulding</span> what happens if you move that type assertion into the closure? Or some similar method to make it so the compiler knows it can only make it work by taking ownership of chunk</p>



<a name="231279293"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Why%20would%20a%20for%20loop%20not%20force%20a%20move%20into%20a%20closure%3F/near/231279293" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Matthew Jasper <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Why.20would.20a.20for.20loop.20not.20force.20a.20move.20into.20a.20closure.3F.html#231279293">(Mar 22 2021 at 09:02)</a>:</h4>
<p><code>&amp;[u64]</code> is <code>Copy</code>, so there's no need for a move.</p>



<a name="231304440"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/122651-general/topic/Why%20would%20a%20for%20loop%20not%20force%20a%20move%20into%20a%20closure%3F/near/231304440" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jake Goulding <a href="https://rust-lang.github.io/zulip_archive/stream/122651-general/topic/Why.20would.20a.20for.20loop.20not.20force.20a.20move.20into.20a.20closure.3F.html#231304440">(Mar 22 2021 at 12:53)</a>:</h4>
<p>Haha, this is the same thing that came up in the last training in a different form. <a class="stream-topic" data-stream-id="122651" href="/#narrow/stream/122651-general/topic/When.20is.20Copy.20applied.20to.20captured.20values.3F">#general &gt; When is Copy applied to captured values?</a></p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>